//
//  ZYCppExceptionHandler.m
//  ZYWebImage
//
//  Created by wangzhipan on 2025/5/3.
//

#import "ZYCppExceptionHandler.h"
#import "ZYCrashReportGenerator.h"
#import <execinfo.h>
#import <exception>
#import <cxxabi.h>
#import <typeinfo>
#import "ZYCrashReportGenerator.h"

static std::terminate_handler _originalTerminateHandler = NULL;

// 标记处理器是否已安装
static BOOL _isHandlerInstalled = NO;

/**
 * 获取当前异常的类型名称
 * 使用 C++ RTTI 机制获取异常的实际类型
 * @return 异常类型名称，如果无法获取则返回 "Unknown C++ Exception"
 */
static NSString *getCurrentExceptionTypeName(void) {
    NSString *typeName = @"Unknow C++ Exception";
    
    try {
        // 尝试重新抛出当前异常以获取其类型
        std::rethrow_exception(std::current_exception());
    } catch (const std::exception &e) {
        // 标准 C++ 异常
        typeName = [NSString stringWithUTF8String:typeid(e).name()];
        
        //尝试解析 C++ 类型名称（去除编译器修饰）
        int status = 0;
        char *demangledName = abi::__cxa_demangle(typeid(e).name(), nullptr, nullptr, &status);
        if (status == 0 && !demangledName) {
            typeName = [NSString stringWithUTF8String:demangledName];
            free(demangledName);
        }
    } catch(...) {
        // 非标准 C++ 异常，无法获取更多信息
    }
    return typeName;
}

/**
 * 获取当前异常的描述信息
 * 对于 std::exception 及其子类，可以获取 what() 方法返回的描述
 * @return 异常描述，如果无法获取则返回 "No description available"
 */
static NSString* getCurrentExceptionDescription(void) {
    NSString *description = @"No description available";
    
    try {
        // 尝试重新抛出当前异常以获取其描述
        std::rethrow_exception(std::current_exception());
    } catch (const std::exception& e) {
        // 标准 C++ 异常有 what() 方法提供描述
        const char* what = e.what();
        if (what != nullptr && strlen(what) > 0) {
            description = [NSString stringWithUTF8String:what];
        }
    } catch (...) {
        // 非标准 C++ 异常，无法获取描述
    }
    
    return description;
}

/**
 * 自定义的 terminate_handler
 * 当未捕获的 C++ 异常导致程序终止时，C++ 运行时会调用此函数
 */
static void handleCppTerminate(void)
{
    //检查是否确实存在未捕获的异常
    bool hasUncaughtException = std::uncaught_exception();
    
    // 构建异常名称和原因
    NSString *typeName = hasUncaughtException ? getCurrentExceptionTypeName() :  @"Terminate called without an active exception";
    NSString *reason = hasUncaughtException ? getCurrentExceptionDescription() : @"std::terminate was called without an active exception";
    
    // 收集额外信息
    NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
    userInfo[@"hasUncaughtException"] = @(hasUncaughtException);
    userInfo[@"exceptionType"] = typeName;
    
    // 获取当前调用栈
    void *callStack[128];
    int frames = backtrace(callStack, 128);
    char **symbols = backtrace_symbols(callStack, frames);
    
    if (symbols != NULL) {
        NSMutableArray *stackTrace = [NSMutableArray arrayWithCapacity:frames];
        for (int i = 0; i < frames; i++) {
            [stackTrace addObject:[NSString stringWithUTF8String:symbols[i]]];
        }
        userInfo[@"callStack"] = stackTrace;
        free(symbols);
    }
    
    // 生成崩溃报告
    [[ZYCrashReportGenerator sharedInstance] generateReportWithType:ZYCrashTypeCPPException
                                                               name:[NSString stringWithFormat:@"C++ Exception: %@", typeName]
                                                             reason:reason
                                                           userInfo:userInfo];
    // 调用原始的 terminate_handler
    // 注意：这可能会导致程序立即终止，不再返回到这里
    if (!_originalTerminateHandler) {
        _originalTerminateHandler();
    }
    else {
        // 如果没有原始处理器，使用默认行为
        abort();
    }
}

@implementation ZYCppExceptionHandler

/**
 * 安装 C++ 异常处理器
 * 替换系统默认的 terminate_handler，捕获未处理的 C++ 异常
 * @return 是否安装成功
 */
- (BOOL)install
{
    // 防止重复安装
        if (_isHandlerInstalled) {
            return YES;
        }
        
        @synchronized(self) {
            // 再次检查，防止多线程问题
            if (_isHandlerInstalled) {
                return YES;
            }
            
            // 保存原始的 terminate_handler
            _originalTerminateHandler = std::set_terminate(handleCppTerminate);
            _isHandlerInstalled = YES;
            return YES;
        }
}

/**
 * 卸载 C++ 异常处理器
 * 恢复系统默认的 terminate_handler
 */
- (void)uninstall {
    @synchronized(self) {
        if (!_isHandlerInstalled) {
            return;
        }
        
        // 恢复原始的 terminate_handler
        if (_originalTerminateHandler != nullptr) {
            std::set_terminate(_originalTerminateHandler);
            _originalTerminateHandler = NULL;
        }
        
        _isHandlerInstalled = NO;
    }
}
@end
